﻿//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Query Application Block
//===============================================================================

using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder;
using Microsoft.Practices.ObjectBuilder2;
using EntLibContrib.Query.Instrumentation;

namespace EntLibContrib.Query.Configuration
{
	/// <summary>
	/// Helper utility for assembler and policy creators
	/// </summary>
	public static class QueryAssemblerHelper
	{
		#region Fields
		private readonly static ConfigurationReflectionCache localReflectionCache = new ConfigurationReflectionCache();
		#endregion

		#region Public Static Methods
		/// <summary>
		/// Creates a parameter dictionary.
		/// </summary>
		/// <param name="parameters">The parameters.</param>
		/// <param name="context">The object builder context.</param>
		/// <param name="configurationSource">The configuration source.</param>
		/// <param name="reflectionCache">The reflection cache.</param>
		/// <returns>a populated <see cref="ParameterDictionary"/> instance from configuration</returns>
		public static ParameterDictionary CreateParameterDictionary(NamedElementCollection<ParameterData> parameters,
																																IBuilderContext context,
																																IConfigurationSource configurationSource,
																																ConfigurationReflectionCache reflectionCache)
		{
			ConfigurationReflectionCache configurationReflectionCache = reflectionCache;
			if (configurationReflectionCache == null)
				configurationReflectionCache = localReflectionCache;

			ParameterDictionary parameterDictionary = new ParameterDictionary();

			foreach (ParameterData parameterData in parameters)
			{
				IParameter parameter = ParameterCustomFactory.Instance.Create(context, parameterData, configurationSource, configurationReflectionCache);
				parameterDictionary.Add(parameter.Name, parameter);
			}

			return parameterDictionary;
		}

		/// <summary>
		/// Creates a parameter set from configuration.
		/// </summary>
		/// <param name="name">The parameter set instance name.</param>
		/// <returns>
		/// the specified <see cref="IParameterSet"/> from configuration
		/// </returns>
		public static IParameterSet CreateParameterSet(string name)
		{
			if (string.IsNullOrEmpty(name))
				return new ParameterSet();
			else
				return ParameterSetFactory.CreateParameterSet(name);
		}

		/// <summary>
		/// Creates a custom command from configuration.
		/// </summary>
		/// <param name="name">The custom command instance name.</param>
		/// <returns>
		/// the specified <see cref="ICustomCommand"/> from configuration
		/// </returns>
		public static ICustomCommand CreateCustomCommand(string name)
		{
			if (string.IsNullOrEmpty(name))
				return null;
			else
			{
				return CustomCommandFactory.CreateCustomCommand(name);
			}
		}

		/// <summary>
		/// Creates an instrumentation provider.
		/// </summary>
		/// <param name="name">The name.</param>
		/// <param name="configurationSource">The configuration source.</param>
		/// <param name="reflectionCache">The reflection cache.</param>
		/// <returns></returns>
		public static QueryInstrumentationProvider CreateInstrumentationProvider(string name,
																																						IConfigurationSource configurationSource,
																																						ConfigurationReflectionCache reflectionCache)
		{
			ConfigurationReflectionCache configurationReflectionCache = reflectionCache;
			if (configurationReflectionCache == null)
				configurationReflectionCache = localReflectionCache;

			QueryInstrumentationProvider instrumentationProvider = new QueryInstrumentationProvider();
			new InstrumentationAttachmentStrategy().AttachInstrumentation(name, instrumentationProvider, configurationSource, configurationReflectionCache);

			return instrumentationProvider;
		}
		#endregion
	}
}
